/* implements the functions defined in display.h */

#include "display.h"

/* prints a string on the LCD display. Returns 1 if the operation is successful, 0 otherwise. Data must be a null terminated string  */

int32_t print_lcd(const char* data){
  if(data == NULL)
    return 0;
  malta_lcd_print(data);
  return 1;
}


/* prints the string data on the tty0 console. Returns 1 if the operation is sucessful, 0 otherwise. data must be a null-terminated string. */
int32_t print_string(const char* data){
  PCB* caller = get_running();
  int32_t r;
  //we check there is something to print
  if(data == NULL)
    return 0;
  if(data[0] == '\0')
    return 1; //this is not an error case. 
  //requesting the device
  r = get_uart(caller);
  if(r == 1){
    //device acquired
    //the caller is blocked until the I/O is done
    block_pcb(caller);
    //this process is doing IO
    pcb_set_state(caller, DOING_IO_UART_STATE);
    //sets UART global variables
    set_printing_mode(data);
    //starts the printing
    print();
    return 2; //fake return value
    //the real return value will be inserted directly into the saved registers at the end of the printing
  }else
    return r; //either an error occured or the caller is now waiting in the device queue
}

/* reads a string from the user using the tty0 device. It reads until the user presses enter or up to length-1 characters. The characters read are put in data and the null character is appended at the end. It returns 1 if the operation is successful, 0 otherwise. It also prints what has been read. */
int32_t read_string(char* data, int32_t length){
  PCB* caller = get_running();
  int32_t r;
  //we check we can store data somewhere
  if(data == NULL || length == 0)
    return 0; //an empty string would mean a string without '\0', impossible
  if(length == 1){
    data[0] = '\0';
    return 1; //this is not an error case. 
  }
  //requesting the device
  r = get_uart(caller);
  if(r == 1){
    //device acquired
    //blocks the caller
    block_pcb(caller);
    //this process is doing IO
    pcb_set_state(caller, DOING_IO_UART_STATE);
    //sets the correct mode
    set_reading_mode(data, length);
    //starts reading
    read();
    return 2; //fake return value
  }else
    return r; 
}
